package com.tanhua.dubbo.server.api;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.enums.CommentType;
import com.tanhua.dubbo.server.pojo.Comment;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;

@Service(version = "1.0.0")
@Slf4j
@SuppressWarnings("all")
public class LoveQuanZiApiImpl implements LoveQuanZiApi {

    //评论数据存储在Redis中key的前缀
    private static final String COMMENT_REDIS_KEY_PREFIX = "QUANZI_COMMENT_";


    //用户是否喜欢的前缀
    private static final String COMMENT_USER_LOVE_REDIS_KEY_PREFIX = "USER_LOVE_";

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private PublicQuanZiImpl publicQuanZiImpl;


    private String getCommentRedisKeyPrefix(String publishId) {
        return COMMENT_REDIS_KEY_PREFIX + publishId;
    }

    private String getCommentUserLoveRedisKey(Long userId) {
        return COMMENT_USER_LOVE_REDIS_KEY_PREFIX + userId;
    }


    /**
     * 喜欢
     *
     * @param userId
     * @param publishId
     * @return
     */
    @Override
    public Boolean loveComment(Long userId, String publishId) {
        //1.判断该用户是否喜欢，如果是喜欢就直接返回
        if (queryUserIsLove(userId, publishId)) {
            return false;
        }

        //喜欢
        Boolean result = publicQuanZiImpl.saveComment(userId, publishId, CommentType.LOVE, null);
        if (!result){
            return false;
        }

        //喜欢成功后，修改Redis中的总的喜欢数
        String redisKey=getCommentRedisKeyPrefix(publishId);
        String hashKey=CommentType.LOVE.toString();
        redisTemplate.opsForHash().increment(redisKey,hashKey,1);

        //标记用户已经喜欢
        hashKey=getCommentUserLoveRedisKey(userId);
        redisTemplate.opsForHash().put(redisKey,hashKey,"1");
        return true;
    }

    /**
     * 取消喜欢
     *
     * @param userId
     * @param publishId
     * @return
     */
    @Override
    public Boolean disLoveComment(Long userId, String publishId) {
        if (!queryUserIsLove(userId,publishId)){
            //如果用户没有喜欢，就直接返回
            return false;
        }

        Boolean result = removeComment(userId, publishId, CommentType.LOVE);
        if (!result){
            //删除失败
            return false;
        }

        //删除redis中的记录
        String redisKey=getCommentRedisKeyPrefix(publishId);
        String hashKey=getCommentUserLoveRedisKey(userId);
        redisTemplate.opsForHash().delete(redisKey,hashKey);
        redisTemplate.opsForHash().increment(redisKey,CommentType.LOVE.toString(),-1);

        return true;
    }

    /**
     * 查询喜欢数
     *
     * @param publishId
     * @return
     */
    @Override
    public Long queryLoveCount(String publishId) {
        //首先从redis中命中，如果命中的话就返回，没有命中就查询Mongodb
        String redisKey = getCommentRedisKeyPrefix(publishId);
        String hashKey = CommentType.LOVE.toString();
        Object value = redisTemplate.opsForHash().get(redisKey, hashKey);

        if (ObjectUtil.isNotEmpty(value)){
            return Convert.toLong(value);
        }

        //查询count
        Long count = queryCommentCount(publishId, CommentType.LOVE);

        //存储到redis中
        redisTemplate.opsForHash().put(redisKey,hashKey,String.valueOf(count));

        return count;
    }

    /**
     * 查询用户是否喜欢该动态
     *
     * @param userId
     * @param publishId
     * @return
     */
    @Override
    public Boolean queryUserIsLove(Long userId, String publishId) {
        //从redis中查询数据
        String redisKey = getCommentRedisKeyPrefix(publishId);
        String hashKey = getCommentUserLoveRedisKey(userId);
        Object value = redisTemplate.opsForHash().get(redisKey, hashKey);

        if (ObjectUtil.isNotEmpty(value)) {
            return StrUtil.equals(Convert.toStr(value),"1");
        }

        //查询mongodb
        Query query = Query.query(Criteria.where("publishId").is(publishId)
                .and("userId").is(userId)
                .and("commentType").is(CommentType.LOVE.getType()));
        long count=mongoTemplate.count(query, Comment.class);

        if (count == 0){
            return false;
        }

        //标记用户已经喜欢
        redisTemplate.opsForHash().put(redisKey,hashKey,"1");

        return true;
    }




    /**
     * 查询数量
     *
     * @param publishId
     * @param commentType
     * @return
     */
    private Long queryCommentCount(String publishId, CommentType commentType) {

        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId))
                .and("commentType").is(commentType));
        long count = mongoTemplate.count(query, Comment.class);
        return count;
    }

    /**
     * 删除喜欢数据
     *
     * @param userId
     * @param publishId
     * @param commentType
     * @return
     */
    private Boolean removeComment(Long userId, String publishId, CommentType commentType) {
        Query query = Query.query(Criteria.where("userId").is(userId)
                .and("publishId").is(new ObjectId(publishId))
                .and("commentType").is(commentType.getType()));
        long deletedCount = mongoTemplate.remove(query, Comment.class).getDeletedCount();

        return deletedCount > 0;
    }

}
